package seu.xml.analysis;

import java.util.ArrayList;

import seu.architecture.simulation.SequenceFurtherAnalysis;
/**
 * 初步解析核心类，，解析出UML图中实体与哪些关系有关，
 * 实体是否被嵌套以及嵌套别的实体，关系除了连接实体，
 * 是否连接了其他关系，是否有多条关系与其相关以及关系
 * 是否在实体内部。最终将这些解析得到的信息进行存储
 * @author cy
 *
 */
public class UMLERDiagram {
	//存储实体和关系，实体和关系都用id识别
	public ArrayList<UMLEntity> ue;
	public ArrayList<UMLRelation> ur;
	/**
	 * 由Diagram类初始化，解析出类图的实体和关系
	 * @param dg 第一步总体解析得出的类
	 */
	public UMLERDiagram(Diagram dg){
		int ueid = 0,urid = 0;
		ue = new ArrayList<UMLEntity>();
		ur = new ArrayList<UMLRelation>();
		ArrayList<Element> classElement = dg.getDiagram();
		for(Element em : classElement){
			if(em.getType().equals("com.umlet.element.Relation"))
				ur.add(new UMLRelation(urid++,em));
			else{
				ue.add(new UMLEntity(ueid++,em));
				//System.out.println(em.getX()+"--"+em.getY()+"--"+em.getW()+"--"+em.getH());
			}
		}
		int xStart,yStart,xEnd,yEnd;
		//获得实体和实体的嵌套关系
		for(UMLEntity uty1 : ue){
			for(UMLEntity uty2 : ue){
				if(uty1.getId() == uty2.getId()) continue;
				if(uty1.hasinternalEntity(uty2.getX(), uty2.getY(), uty2.getW(), uty2.getH())){
					uty1.internalEntity.add(uty2.getId());
					uty2.externalEntity.add(uty1.getId());
				}
			}
		}
		for(UMLRelation uen : ur){
			String[] s = uen.UMLRelationElement.getAdditional_attributes().split(";");
			xStart = uen.UMLRelationElement.getX()+Integer.parseInt(s[0]);
			yStart = uen.UMLRelationElement.getY()+Integer.parseInt(s[1]);			
			xEnd = uen.UMLRelationElement.getX()+Integer.parseInt(s[s.length-2]);
			yEnd = uen.UMLRelationElement.getY()+Integer.parseInt(s[s.length-1]);
			//获得实体和关系的关联情况，包括包含和相关
			for(UMLEntity uty : ue){
				
				if(uty.UMLEntityElement.getType().equals("com.umlet.element.custom.SeqDestroyMark")
						||uty.UMLEntityElement.getType().equals("com.umlet.element.Actor")
						||uty.UMLEntityElement.getType().equals("com.umlet.element.UseCase")){
					if(uty.hasPointIn(xStart, yStart)){
						uen.setStartEntityID(uty.getId());
						uty.ralationID.add(uen.getId());					
					}					
					if(uty.hasPointIn(xEnd, yEnd)){
						uen.setEndEntityID(uty.getId());
						uty.ralationID.add(uen.getId());
					}
				}else{	
					//实体通过关系自身调用自身的情况需要考虑
					if(uty.hasPoint(xStart, yStart)){
						uen.setStartEntityID(uty.getId());
						uty.ralationID.add(uen.getId());
					}					
					if(uty.hasPoint(xEnd, yEnd)){
						uen.setEndEntityID(uty.getId());
						uty.ralationID.add(uen.getId());
					}
					if(uty.hasinternalRelation(xStart,yStart,xEnd,yEnd)){
						uty.internalRelation.add(uen.getId());
						uen.externalEntity.add(uty.getId());
					}
				}
			}
			//获得关系和关系的关联情况
			for(UMLRelation uen1 : ur){
				if(uen1.getId() == uen.getId()) continue;
				//if(uen.getId()==8) System.out.println(uen1.hasRelation(xStart, yStart));
				if(uen1.hasPoint(xStart, yStart)){
					uen1.relevanceRelation.add(uen.getId());
					uen.setStartRelationID(uen1.getId());
				}
				if(uen1.hasPoint(xEnd, yEnd)){
					uen1.relevanceRelation.add(uen.getId());
					uen.setEndRelationID(uen1.getId());
				}
			}
		}
		//printClassDiagram();
	}
	public void printClassDiagram(){
		//测试关系属性的关联
		System.out.println("---------------测试关系属性的关联---------------");
		for(UMLRelation ure : ur){
			System.out.print("关系属性："+ure.UMLRelationElement.getPanel_attributes());
			if(ure.getStartEntityID()!=-1)
				System.out.print("|起始实体"+ue.get(ure.getStartEntityID()).UMLEntityElement.getPanel_attributes());
			if(ure.getStartRelationID()!=-1)
				System.out.print("|起始关系"+ur.get(ure.getStartRelationID()).UMLRelationElement.getPanel_attributes()+"|id:"+ure.getStartRelationID());
			if(ure.getEndEntityID()!=-1)
				System.out.println("|结束实体"+ue.get(ure.getEndEntityID()).UMLEntityElement.getPanel_attributes());
			if(ure.getEndRelationID()!=-1){
				System.out.println("|结束关系"+ur.get(ure.getEndRelationID()).UMLRelationElement.getPanel_attributes()+"|id:"+ure.getEndRelationID());
			}
			System.out.println("--------------------");
		}
		
		//modified by Samantha
//		Iterator<Integer> it;
//		for(UMLEntity uel : ue){
//			it=uel.ralationID.iterator();
//			System.out.println( "实体类型："+uel.UMLEntityElement.getType() );
//			while( it.hasNext() ){
//				System.out.println( "关系"+ it.next()  );		
//			}	
//			System.out.println();
//		}
		//modification ends
		//实体类内部嵌套实体类测试
		System.out.println("---------------实体类内部嵌套实体类测试---------------");
		for(UMLEntity uey : ue){
			if(uey.internalEntity.size()!=0){
				System.out.println("实体："+uey.UMLEntityElement.getPanel_attributes());
				for(Integer id : uey.internalEntity){
					System.out.println("|内部实体："+ue.get(id).UMLEntityElement.getPanel_attributes());
				}
			}
		}
		//实体类外部包含哪些实体类测试
		System.out.println("---------------实体类外部包含哪些实体类测试---------------");
		for(UMLEntity uey : ue){
			if(uey.externalEntity.size()!=0){
				System.out.print("实体："+uey.UMLEntityElement.getPanel_attributes());
				for(Integer id : uey.externalEntity){
					System.out.print("|外部实体："+ue.get(id).UMLEntityElement.getPanel_attributes());
				}
				System.out.println();
			}
		}
		//实体类内部包含关系测试
		System.out.println("---------------实体类内部包含关系测试---------------");
		for(UMLEntity uey : ue){
			if(uey.internalRelation.size()!=0){
				System.out.print("实体："+uey.UMLEntityElement.getPanel_attributes());
				for(Integer id : uey.internalRelation){
					System.out.print("|内部关系："+ur.get(id).UMLRelationElement.getPanel_attributes());
				}
				System.out.println();
			}
		}
		//关系在哪些实体内部测试
		System.out.println("---------------关系在哪些实体内部测试---------------");
		for(UMLRelation uen : ur){			
			if(uen.externalEntity.size()!=0){
				System.out.print("关系属性："+uen.UMLRelationElement.getPanel_attributes());
				for(Integer id : uen.externalEntity){
					System.out.print("|实体:"+ue.get(id).UMLEntityElement.getPanel_attributes());
				}
				System.out.println();
			}			
		}
		//关系与那些关系关联
		System.out.println("---------------关系与那些关系关联测试---------------");
		for(UMLRelation uen : ur){
			if(uen.relevanceRelation.size()!=0){
				System.out.println("关系属性："+uen.UMLRelationElement.getPanel_attributes());
				for(Integer id : uen.relevanceRelation){
					System.out.print("|关系:"+ur.get(id).UMLRelationElement.getPanel_attributes());
				}
				System.out.println("----------------------------------");
			}
		}
	}
	

	
	public static void main(String[] args){
		Diagram dg = new Diagram();
		//dg.readXML("new.uxf");
		//dg.readXML("shunxutu.uxf");
		//dg.readXML("testsimple.uxf");
		//dg.readXML("testcomplex2.uxf");
		dg.readXML("K:\\testRead.uxf");
		UMLERDiagram temp = new UMLERDiagram(dg);
		//temp.printClassDiagram();
		System.out.println(temp.ur.get(0).UMLRelationElement.getPanel_attributes());
		//System.out.println(SequenceFurtherAnalysis.readTime(temp.ur.get(0).UMLRelationElement.getPanel_attributes()));
		//System.out.println(SequenceFurtherAnalysis.readResource(temp.ur.get(0).UMLRelationElement.getPanel_attributes()));
	}
}
